//@author A0105730U
#pragma once
#ifndef ANALYZER_H
#define ANALYZER_H
#include <string>
#include <vector>
#include "Command.h"

#include "CommandAdd.h"
#include "CommandDelete.h"
#include "CommandUpdate.h"
#include "CommandInvalid.h"
#include "CommandSearch.h"
#include "CommandMark.h"
#include "CommandDisplay.h"
#include "CommandRead.h"
#include "CommandCheck.h"
#include "Parser_Importance.h"
#include "DateTime.h"
#include "Invoker.h"
#include "Parser_Location.h"
#include "assert.h"

#include "DateTimeLocator.h"


//@author A0100617W
const std:: string TIME_INDICATOR_ANALYZER ="t[";
const std:: string QUOTE_BLANK_ANALYZER =" ";
const std:: string TO_FLOATING_EVENT_ANALYZER = "to floating event";
const std:: string TO_FLOATING_ANALYZER = "to floating";
const std:: string TO_FLOAT_ANALYZER = "to float";
const std:: string FLOAT_ANALYZER = "float";
const std:: string FLOATING_ANALYZER = "floating";
const std:: string NOT_FOUND_STRING_ANALYZER = " \",./?';:{}\\|<>=+-_)(*&^%$#@!~`";
const std:: string QUOTE_ANALYZER= "";
const std:: string INSTRUCTION_ADD_ANALYZER= "add";
const std:: string INSTRUCTION_DELETE_ANALYZER= "delete";
const std:: string INSTRUCTION_UPDATE_ANALYZER= "update";
const std:: string INSTRUCTION_SEARCH_ANALYZER= "search";
const std:: string INSTRUCTION_DISPLAY_ANALYZER= "display";
const std:: string INSTRUCTION_READ_ANALYZER= "read";
const std:: string INSTRUCTION_DONE_ANALYZER= "done";
const std:: string INSTRUCTION_CHECK_ANALYZER= "check";
const std:: string BLANK_COMMA_DOT_ANALYZER = " ,.";
const std:: string LOG_MESSAGE_ONE_ANALYZER ="Analyzer splits user input to two parts: instruction and content";
const std:: string UNDO_ANALYZER = "undo";
const std:: string LOG_MESSAGE_TWO_ANALYZER ="Analyzer calls the Executer to undo the last opertion";
const std:: string LOG_MESSAGE_THREE_ANALYZER ="Analyzer intepret user's instruction and get CommandType";
const std:: string LOG_MESSAGE_FOUR_ANALYZER ="Analyzer pass a command_Read to executer";
const std:: string LOG_MESSAGE_FIVE_ANALYZER ="Analyzer pass a command_Update to executer";
const std:: string LOG_MESSAGE_SIX_ANALYZER ="Analyzer pass a command_Add to executer";
const std:: string LOG_MESSAGE_SEVEN_ANALYZER ="Analyzer pass an invalid command_Add to executer";
const std:: string LOG_MESSAGE_EIGHT_ANALYZER ="Analyzer pass a command_Delete to executer";
const std:: string LOG_MESSAGE_NINE_ANALYZER ="Analyzer pass an invalid command_Delete to executer";
const std:: string LOG_MESSAGE_TEN_ANALYZER ="Analyzer pass a command_Mark to executer";
const std:: string LOG_MESSAGE_ELEVEN_ANALYZER ="Analyzer pass an invalid command_Mark to executer";
const std:: string LOG_MESSAGE_TWELVE_ANALYZER ="Analyzer pass a command_Update to executer";
const std:: string LOG_MESSAGE_THIRTEEN_ANALYZER ="Analyzer pass an invalid command_Update to executer";
const std:: string LOG_MESSAGE_FOURTEEN_ANALYZER ="Analyzer pass an invalid command_Update to executer";
const std:: string LOG_MESSAGE_FIFTEEN_ANALYZER ="Analyzer pass an invalid command_Search to executer";
const std:: string LOG_MESSAGE_SIXTEEN_ANALYZER ="Analyzer pass a command_Display to executer";
const std:: string LOG_MESSAGE_EIGHTEEN_ANALYZER ="Analyzer pass an invalid command_Display to executer";
const std:: string LOG_MESSAGE_NINETEEN_ANALYZER ="Analyzer pass a command_Invalid to executer";




class Analyzer{
private:	
	CommandType _commandType;
	Invoker _theE;
	int _searchId;

public:
	void splitInput(std::string, std::string&, std::string&);
	std::vector<std::string> cutStringToPieces(std::string);
	DateTime StringToDT(std::string);
	CommandAdd intepret_Add(std::string);
	CommandDelete intepret_Delete(std::string);
	CommandMark intepret_Mark(std::string);
	CommandDisplay intepret_Display(std::string);
	CommandUpdate intepret_Update(std::string);
	CommandSearch intepret_Search (std::string);
	CommandType getCommandType(std::string);
	Command intepret(std::string);
	Command fakeACommand(int);
	Importance stringToImpo(std::string);
	std::string seperateID(std::string, std::string&);
	void fillDateTimeWithTimeString(DateTime&, std::string);
	void fillDateTimeWithDateString(DateTime&, std::string);
	std::string clear_Space_Punctuation(std::string);
	bool checkFloating(std::string);
	bool TwoDatesAreInOrder(DateTime, DateTime);
	bool DateTimeIsValid(DateTime);
	bool isLeapyear(int);
	bool findStrictTimePiece(std::string, std::string&, size_t&, size_t&);
	Feedback process_Analyzer(std::string);
	Analyzer();
	void readfile(std::string);
	~Analyzer(void);
};
#endif
